package org.meetunexpectedly.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @Description: JWT工具，生成token
 * @Author: pupil
 * @Date: 2024/08/04 下午 7:39
 */
public class JwtUtils {

    //常量
    private static final long EXPIRE = 1000 * 60 * 60 * 24; //token过期时间
    private static final String APP_SECRET = "cHVwaWxNeUxvdmU="; //秘钥

    public static String getJwtToken(Long id, String nickName) {
        String token = Jwts.builder()
                // header（JWT头部）
                .setHeaderParam("typ", "JWT") // 类别
                .setHeaderParam("alg", "HS256") //加密算法

                .setSubject("login-user") // 主题
                .setIssuedAt(new Date()) // 创建时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) // 过期时间

                // payload（设置token主体部分）
                .claim("id", String.valueOf(id)) // id
                .claim("nickName", nickName)
                // signature
                .signWith(SignatureAlgorithm.HS256, APP_SECRET) // 使用指定算法
                .compact();
        return token;
    }

    /**
     * 判断token是否存在与有效
     *
     * @param request 请求
     * @return
     */
    public static Boolean checkToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("token");
            if (ObjectUtils.isEmpty(jwtToken)) return false;
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 解析token获取用户id
     *
     * @param request
     * @return
     */
    public static Long getUserId(HttpServletRequest request) {
        String jwtToken = request.getHeader("token");
        if (ObjectUtils.isEmpty(jwtToken)) return null;

        Claims claims = Jwts.parser() // 创建一个 JWT 解析器的实例
                .setSigningKey(APP_SECRET) // 使用相同的签名密钥
                .parseClaimsJws(jwtToken) // 方法将传入的 token 进行解析
                .getBody();
        return Long.valueOf(claims.get("id").toString());
    }
}
